package com.wang.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.project.common.ErrorCode;
import com.wang.project.exception.BusinessException;
import com.wang.project.model.dto.refreshKey.OrderRefreshKeyQueryRequest;
import com.wang.project.model.modle.PayModel;
import com.wang.project.model.vo.pay.OrderRefreshKeyVO;
import com.wang.project.utils.CommonUtils;
import com.wang.project.constant.MQConstant;
import com.wang.project.constant.PaymentEnum;
import com.wang.project.model.entity.Payment;
import com.wang.project.model.entity.User;
import com.wang.project.pay.zfb.AlipayFaceToFaceService;
import com.wang.project.pay.zfb.ZFBPreorderActionVO;
import com.wang.project.service.PaymentService;
import com.wang.project.mapper.PaymentMapper;
import com.wang.project.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 胡歌的腿毛
 * @description 针对表【payment】的数据库操作Service实现
 * @createDate 2023-09-14 19:59:21
 */
@Service
@Slf4j
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment>
        implements PaymentService {
    /**
     * 在返回二维码之前，先将支付信息存在表中，支付完成之后再更新表的信息
     */

    private final static Map<String, Double> payAmountMap = new HashMap<>();
    private final static Map<String, String> payOrderNumberPreFixMap = new HashMap<>();


    private final static String sourceScene = "支付宝"; //支付场景

    static {
        payAmountMap.put("refreshKey", 9.9);

        payOrderNumberPreFixMap.put("refreshKey", "AS"); //刷新key的订单号前缀
    }

    @Resource
    private UserService userService;

    @Resource
    private AlipayFaceToFaceService alipayFaceToFaceService;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 获取刷新key的二维码 同时组装刷新key的参数 发送mq消息 最后返回二维码
     *
     * @param request
     * @param response
     * @return
     */
    @Override
    public ZFBPreorderActionVO getPayToRefreshKey(HttpServletRequest request, HttpServletResponse response) {
        final String subject = "开通永久不刷新key的vip服务";

        //组装参数
        PayModel payModel = new PayModel();
        User loginUser = userService.getLoginUser(request);
        payModel.setUser(loginUser);
        payModel.setAmount(payAmountMap.get("refreshKey"));
        payModel.setPayCount(1);
        payModel.setSubject(subject);
        String alipayOutTradeNo = CommonUtils.getAlipayOutTradeNo(payOrderNumberPreFixMap.get("refreshKey"));
        payModel.setOrderNumber(alipayOutTradeNo);

        //支付逻辑 返回支付二维码
        ZFBPreorderActionVO zfbPreorderActionVO = alipayFaceToFaceService.ZFBPreorderAction(request, response, payModel);

        //发送mq消息，保存支付信息
        Payment payment = new Payment();
        payment.setPaymentOrder(alipayOutTradeNo);
        payment.setAmount(BigDecimal.valueOf(payAmountMap.get("refreshKey")));
        payment.setPayStatus(PaymentEnum.UnPay.getCode());
        payment.setUserId(loginUser.getId());
        payment.setSourceScene(sourceScene);
        payment.setUserName(loginUser.getUserName());
        rocketMQTemplate.asyncSend(MQConstant.TOPIC_PAYMENT_REFRESHKEY, payment, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("发送消息成功");
            }

            // todo 当消息失败后，将消息放入死信队列 等待后续消息补偿
            @Override
            public void onException(Throwable throwable) {
                log.info("发送消息失败,等待补偿操作");
            }
        });

        zfbPreorderActionVO.setSubject(subject);
        zfbPreorderActionVO.setAmount(payAmountMap.get("refreshKey"));
        return zfbPreorderActionVO;
    }


    /**
     * 查询所有list
     *
     * @param orderRefreshKeyQueryRequest
     * @param request
     * @return
     */
    @Override
    public List<OrderRefreshKeyVO> getPaymentListQuery(OrderRefreshKeyQueryRequest orderRefreshKeyQueryRequest, HttpServletRequest request) {
        if (orderRefreshKeyQueryRequest == null) {
            log.info("PaymentServiceImpl getPaymentListQuery orderRefreshKeyQueryRequest is null");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Payment payment = new Payment();
        BeanUtils.copyProperties(orderRefreshKeyQueryRequest, payment);
        QueryWrapper<Payment> paymentQueryWrapper = new QueryWrapper<>(payment);
        List<Payment> paymentList = this.list(paymentQueryWrapper);
        List<OrderRefreshKeyVO> orderRefreshKeyVOS = paymentList.stream().map(item -> {
            OrderRefreshKeyVO orderRefreshKeyVO = new OrderRefreshKeyVO();
            BeanUtils.copyProperties(item, orderRefreshKeyVO);
            return orderRefreshKeyVO;
        }).collect(Collectors.toList());
        return orderRefreshKeyVOS;
    }

    /**
     * 分页查询
     *
     * @param orderRefreshKeyQueryRequest
     * @param request
     * @return
     */
    @Override
    public Page<OrderRefreshKeyVO> listPaymentOrderByPage(OrderRefreshKeyQueryRequest orderRefreshKeyQueryRequest, HttpServletRequest request) {
        long size = 10;
        long current = 1;
        Payment payment = new Payment();
        if (orderRefreshKeyQueryRequest != null) {
            BeanUtils.copyProperties(orderRefreshKeyQueryRequest, payment);
            current = orderRefreshKeyQueryRequest.getCurrent();
            size = orderRefreshKeyQueryRequest.getPageSize();
        }
        QueryWrapper<Payment> queryWrapper = new QueryWrapper<>(payment);
        Page<Payment> paymentPage = this.page(new Page<>(current, size), queryWrapper);
        Page<OrderRefreshKeyVO> orderRefreshKeyVOPage = new PageDTO<>(paymentPage.getCurrent(), paymentPage.getSize(), paymentPage.getTotal());
        List<OrderRefreshKeyVO> orderRefreshKeyVOList = paymentPage.getRecords().stream().map(item -> {
            OrderRefreshKeyVO orderRefreshKeyVO = new OrderRefreshKeyVO();
            BeanUtils.copyProperties(item, orderRefreshKeyVO);
            return orderRefreshKeyVO;
        }).collect(Collectors.toList());
        orderRefreshKeyVOPage.setRecords(orderRefreshKeyVOList);
        return orderRefreshKeyVOPage;
    }
}




